package ngat.oss;

import ngat.message.OSS.*;
import ngat.astrometry.*;
import ngat.util.*;
import ngat.util.logging.*;
import ngat.phase2.*;
import ngat.instrument.*;
import ngat.phase2.nonpersist.*;

import java.util.*;
import java.io.*;
import java.text.*;

import jyd.dbms.*;
import jyd.storable.*;
import jyd.collection.*;

public class SCHEDULABILITYImpl extends TransactionImpl implements Serializable {

    /** The the group whose schedulability we want to test.*/
    protected Group group;
    
    /** The the start of the period we want to check*/
    protected long start;
    
    /** The the end of the period we want to check*/
    protected long end;
    
    /** Resolution to use (ms).*/
    protected long resolution;

    /** Create a SCHEDULABILITYImpl.*/
    public SCHEDULABILITYImpl(SCHEDULABILITY request) {
	super(request);	
	this.group = request.getGroup();
	this.start = request.getStart();
	this.end   = request.getEnd();
	this.resolution = request.getResolution();
    }

     public TRANSACTION_DONE exec() {

	 // We need to access the scheduler (indirectly).
	 // would be good to be able to feed RTI windows into this...

	 long grpNomOff = Group.NOMINAL_OFFSET_TIME;
	 long grpNomAcq = Group.NOMINAL_ACQUIRE_TIME;
	 long grpNomRo  = Group.NOMINAL_READOUT_TIME;
	 long grpNomConf= Group.NOMINAL_CONFIGURATION_TIME;
	    	    
	 try {
	     
	     double score = 0.0;

	     Group.NOMINAL_OFFSET_TIME        = 10000L;
	     Group.NOMINAL_ACQUIRE_TIME       = 60000L;
	     Group.NOMINAL_READOUT_TIME       = 20000L;
	     Group.NOMINAL_CONFIGURATION_TIME = 10000L;
	     
	     // decide what we want to do now...
	     
	     TestContention test = Oss.getInstance().getTeaScoringCalculator();
	     if (test == null)
		 return error(SCHEDULE.SCHEDULER_NOT_AVAILABLE,
			      "No TEA scoring calculator could be found");
	     
	     int num = (int)((end - start)/resolution);
	     
	     System.err.println("Contention test: Using: start = "+sdf.format(new Date(start))+
				", End = "+sdf.format(new Date(end)));
	     
	     test.loadCache();
	     test.loadUnavailableWindows();
	     test.checkWeather();
	     
	     // Scorer will re-calculate its own resolution and Nsamps...
	     TestContention.ScoreInfo info = test.runTestActual(group, start);
	     
	     logger.log(1, "TEA Score at: "+sdf.format(new Date(start))+" "+info);
	     
	     SCHEDULABILITY_DONE done = new SCHEDULABILITY_DONE(id);
	     done.setSchedulability(info.score);
	     done.setDifferentialFunction(info.differential);
	     done.setCumulativeFunction(info.cumulative);
	     done.setSuccessful(true);
	     done.setFailureReasons(info.failureReasons);	     
	     return done;
	     
	 } catch (Exception e) {
	     logger.log(1, CLASS, id, "exec",  "Error during transaction: " + e);
	     e.printStackTrace();
	     return error(TRANSACTION.TRANSACTION_FAILURE, 
			  "Error during transaction: "+ e);
	 } finally {

	     // reset these to previous..
	     Group.NOMINAL_OFFSET_TIME        = grpNomOff;
	     Group.NOMINAL_ACQUIRE_TIME       = grpNomAcq;
	     Group.NOMINAL_READOUT_TIME       = grpNomRo;
	     Group.NOMINAL_CONFIGURATION_TIME = grpNomConf;
	   
	}	


     }

}
